#!/usr/bin/env node
const { join, resolve, dirname } = require('path');
const { readdirSync, mkdirSync, readFileSync, rmSync, writeFileSync } = require('fs');
const { valid, lte, rcompare, prerelease, major, minor, patch } = require('semver');
const glob = require('glob');

const ROOT = resolve(__dirname, '..');

function camelCaseToSentenceCase(str)
{
    const tmp = str.replace(/([A-Z])/g, ' $1');

    return tmp.charAt(0).toUpperCase() + tmp.slice(1);
}

function camelCaseToSnakeCase(str)
{
    return str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
}

async function go()
{
    // Find all pixi-version.json files
    const versionFiles = glob.sync(`${ROOT}/**/pixi-version.json`);
    const TUTORIALS_PATH = resolve(ROOT, 'src', 'tutorials');

    // Read the directories in the tutorials directory
    const tutorialDirectories = readdirSync(TUTORIALS_PATH, { withFileTypes: true })
        .filter((dirent) => dirent.isDirectory())
        .map((dirent) => dirent.name);

    // Perform the script on all the directories that they are in
    for (const versionFile of versionFiles)
    {
        const DOCS_PATH = dirname(versionFile);
        const TUTORIALS_MD_PATH = resolve(DOCS_PATH, 'tutorials');
        const pixiVersion = require(versionFile);
        const VERSION = pixiVersion.version;
        const isPrerelease = prerelease(`v${VERSION}`);
        const versionToCompare = isPrerelease ? `v${major(VERSION)}.${minor(VERSION)}.${patch(VERSION)}` : `v${VERSION}`;

        // Filter and sort the directories to find the best match
        const bestMatch = tutorialDirectories
            // eslint-disable-next-line no-loop-func
            .filter((name) => valid(name) && lte(name, versionToCompare))
            .sort((a, b) => rcompare(a, b))[0];

        console.log(`Generating tutorials for v${VERSION} using the ${bestMatch} source`);

        const TUTORIALS_JS_PATH = resolve(TUTORIALS_PATH, bestMatch);

        const tutorialsData = require(`${TUTORIALS_JS_PATH}/tutorialsData.json`);

        const fileData = tutorialsData.map((tutorialKey) =>
        {
            const mdName = camelCaseToSnakeCase(tutorialKey);
            const title = camelCaseToSentenceCase(tutorialKey);

            return {
                tutorialKey,
                title,
                filePath: `${join(TUTORIALS_MD_PATH, mdName)}.md`,
            };
        });

        // delete old stuff first
        readdirSync(TUTORIALS_MD_PATH, (err, files) =>
        {
            if (err) throw err;

            for (const file of files)
            {
                // Keep index.md
                if (file === 'index.md' || file === '.gitignore') continue;
                rmSync(join(TUTORIALS_MD_PATH, file), { recursive: true, force: true });
            }
        });

        fileData.forEach(({ tutorialKey, title, filePath, hide }, index) =>
        {
            const mdContents = [
                '---',
                'hide_title: true',
                'pagination_next: null',
                'pagination_prev: null',
                'custom_edit_url: null',
                '---',
                '<!-- AUTO-GENERATED BY [generate-tutorial-docs] script -->',
                'import Tutorial from \'@site/src/components/Tutorial/index\';',
                'import version from \'../pixi-version.json\';',
                '',
                `<Tutorial id="${tutorialKey}" pixiVersion={version}/>`,
                '',
            ].join('\n');

            writeFileSync(filePath, mdContents, 'utf8');
        });
    }
}

go();
